namespace Asmex.FileViewer
{
    using Asmex.ObjViewer;
    using System;
    using System.Collections;
    using System.IO;

    public class ImpExports
    {
        private uint[] _expAddrTab;
        private string[] _expNameTab;
        private uint[] _expOrdTab;
        private ExportRecord[] _exports;
        private ExportDirTable _extab;
        private ImportDirectoryEntry[] _ith;

        public ImpExports(BinaryReader reader, MModule mod)
        {
            ArrayList list = new ArrayList();
            ImportDirectoryEntry entry = null;
            this._exports = new ExportRecord[0];
            this._ith = new ImportDirectoryEntry[0];
            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva != 0)
            {
                uint num = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva);
                uint num2 = mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Size + num;
                reader.BaseStream.Position = num;
                while (reader.BaseStream.Position < num2)
                {
                    entry = new ImportDirectoryEntry(reader, mod);
                    if (entry.Name == null)
                    {
                        break;
                    }
                    list.Add(entry);
                }
                this._ith = (ImportDirectoryEntry[]) list.ToArray(typeof(ImportDirectoryEntry));
            }
            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva != 0)
            {
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva);
                this._extab = new ExportDirTable(reader, mod);
                this._expAddrTab = new uint[this._extab.AddressTableEntries];
                this._expNameTab = new string[this._extab.NamePointerCount];
                this._expOrdTab = new uint[this._extab.NamePointerCount];
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(this._extab.ExportAddressTableRVA);
                for (int i = 0; i < this._extab.AddressTableEntries; i++)
                {
                    this._expAddrTab[i] = reader.ReadUInt32();
                }
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(this._extab.OrdinalRVA);
                for (int j = 0; j < this._extab.NamePointerCount; j++)
                {
                    this._expOrdTab[j] = reader.ReadUInt16();
                }
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(this._extab.NamePointerRVA);
                for (int k = 0; k < this._extab.NamePointerCount; k++)
                {
                    this._expNameTab[k] = mod.StringFromRVA(reader, reader.ReadUInt32());
                }
                uint addressTableEntries = this._extab.AddressTableEntries;
                if (addressTableEntries > this._extab.NamePointerCount)
                {
                    addressTableEntries = this._extab.NamePointerCount;
                }
                this._exports = new ExportRecord[addressTableEntries];
                for (int m = 0; m < addressTableEntries; m++)
                {
                    this._exports[m] = new ExportRecord(this._expOrdTab[m], this._expAddrTab[m], this._expNameTab[m]);
                }
            }
        }

        [ObjViewer(false)]
        public ExportDirTable ExportDirectoryTable
        {
            get
            {
                return this._extab;
            }
        }

        [ObjViewer(false)]
        public ExportRecord[] Exports
        {
            get
            {
                return this._exports;
            }
        }

        [ObjViewer(false)]
        public ImportDirectoryEntry[] ImportDirectoryEntries
        {
            get
            {
                return this._ith;
            }
        }
    }
}
